package com.hksj.data.event.listener;

import com.hksj.data.event.WriteParseTdengineDataEvent;
import com.hksj.data.service.DevicePropertyService;
import com.hksj.data.tdengine.annatation.ReflectUtil;
import com.hksj.data.tdengine.annatation.Tags;
import com.hksj.data.tdengine.annatation.Values;
import com.hksj.data.tdengine.entity.Properties;
import com.hksj.data.tdengine.operation.TDengineOperations;
import com.hksj.data.thing.RawData;
import org.influxdb.dto.Point;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author zengke
 * @version 1.0
 * @see WriteParseTdengineDataEventListener
 * @since 2025/08/15 10:24
 */

@Component
public class WriteParseTdengineDataEventListener {


    @Autowired
    private DevicePropertyService devicePropertyService;

    @Autowired(required = false)
    private TDengineOperations tDengineOperations;

    @Async
    @EventListener
    public void onWriteParseTdengineDataEvent(WriteParseTdengineDataEvent event) {

        //获取原始数据
        RawData data = event.getData();

        //获取上报时间戳
        Long timestamp = data.getTimestamp();

        //获取设备id
        String deviceId = data.getDeviceId();

        //判断设备id是否为空
        if (deviceId == null){
            return;
        }

        //获取数据集合
        Map<String, Object> dataMap = data.getDataMap();

        //判断数据集合是否为空
        if (dataMap == null){
            return;
        }

        //遍历数据集合、转换为属性列表
        List<Properties> propertiesList = dataMap.entrySet()
                .stream()
                .map(entry -> {

                    //创建属性对象
                    Properties properties = new Properties();

                    //设置属性对象各属性值
                    properties.setDeviceId(deviceId);
                    properties.setProperty(entry.getKey());
                    properties.setValue(String.valueOf(entry.getValue()));

                    //当前的创建时间
                    properties.setCreateTime(timestamp.doubleValue());

                    //返回属性对象
                    return properties;
                }).collect(Collectors.toList());

        //封装属性列表的属性信息
        devicePropertyService.wrap(propertiesList);

        //将属性列表转换为Point点位列表
        List<Point> points = propertiesList.stream().filter(properties -> StringUtils.hasText(properties.getProductId())).map(properties -> {

            //获取产品id
            String productId = properties.getProductId();

            //获取当前点位的标签集合
            Map<String, String> tagsMap = ReflectUtil.getFieldMapAnnotatedWith(properties, Tags.class).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> String.valueOf(entry.getValue())));

            //获取当前点位的值集合
            Map<String, Object> valuesMap = ReflectUtil.getFieldMapAnnotatedWith(properties, Values.class);

            //创建点位对象
            return Point.measurement(getPropertiesStableName(productId))
                    .tag(tagsMap)
                    .fields(valuesMap)
                    .time(timestamp, TimeUnit.MILLISECONDS)
                    .build();

        }).collect(Collectors.toList());

        //批量写入
        tDengineOperations.forWrite().writeBatch(points);

    }


    public String getPropertiesStableName(String productId){

        return "properties_" + productId;
    }

}
